package com.source.baseData.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.source.baseData.entity.*;
import com.source.baseData.service.*;
import com.source.baseData.vo.EntrustDefaultInfoVO;
import com.source.baseData.vo.EntrustVO;
import com.source.baseData.mapper.EntrustMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.source.utils.*;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Feng
 * @since 2021-02-12
 */
@Service

public class EntrustServiceImpl extends ServiceImpl<EntrustMapper, Entrust> implements EntrustService {

    @Resource
    EntrustMapper entrustMapper;

    @Value("${qrcode.entrust.redis.timeout}")
    private int timeout;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private DateUtils dateUtils;

    @Autowired
    PoultryCategoryService categoryService;

    @Autowired
    ToMarketService marketService;

    @Autowired
    StallsService stallsService;

    @Autowired
    SlaughterHouseService houseService;

    @Override
    public List<EntrustVO> getList() {
        return entrustMapper.listAll();
    }

    @Override
    public Page<EntrustVO> getPage(int current, int size) {
        return entrustMapper.pageAll(new Page<>(current, size));
    }

    @Override
    public boolean cancel(String id) {
        Entrust entrust = getById(id);
        if (entrust == null) {
            return false;
        }
        if (entrust.getStatus() != 1 && entrust.getStatus() != 2) {
            return false;// 该委托已被接单，无法撤销
        }
        entrust.setStatus(0);
        return this.save(entrust) & this.removeById(id);
    }

    @Override
    public String agree(String id) {
        Entrust entrust = this.getById(id);
        if (entrust.getStatus() != 1) {
            return "error";
        }
//        String uuid = UUIDUtils.getUUID22();
//        redisUtil.set(uuid, entrust.getToMarketId(), 30);
        entrust.setStatus(2);
        entrust.setAcceptDate(new Date());
        this.updateById(entrust);
        return "";
    }

    @Override
    public boolean refuse(String id) {
        Entrust entrust = this.getById(id);
        if (entrust.getStatus() != 1) {
            return false;
        }
        entrust.setStatus(3);
        this.updateById(entrust);
        return true;
    }

    @Override
    public EntrustVO getByEntrustId(String id) {
        return entrustMapper.getByEntrustId(id);
    }

    @Override
    public List<EntrustVO> getListByToMarketIdAndStatus(String toMarketId, int status) {
        return entrustMapper.listByToMarketIdAndStatus(toMarketId, status);
    }

    @Override
    public Page<EntrustVO> getPageByToMarketIdAndStatus(String toMarketId, int status, int current, int size) {
        return entrustMapper.pageByToMarketIdAndStatus(toMarketId, status, new Page<>(current, size));
    }

    @Override
    public List<EntrustVO> getListByUserIdAndStatus(String userId, int status) {
        return entrustMapper.listByUserIdAndStatus(userId, status);
    }

    @Override
    public Page<EntrustVO> getPageByUserIdAndStatus(String userId, int status, int current, int size) {
        return entrustMapper.pageByUserIdAndStatus(userId, status, new Page<>(current, size));
    }

    @Override
    public List<EntrustVO> getListByToMarketId(String toMarketId) {
        return entrustMapper.listByToMarketId(toMarketId);
    }

    @Override
    public Page<EntrustVO> getPageByToMarketId(String toMarketId, int current, int size) {
        return entrustMapper.pageByToMarketId(toMarketId, new Page<>(current, size));
    }

    @Override
    public List<EntrustVO> getListByUserId(String userId) {
        return entrustMapper.listByUserId(userId);
    }

    @Override
    public Page<EntrustVO> getPageByUserId(String userId, int current, int size) {
        return entrustMapper.pageByUserId(userId, new Page<>(current, size));
    }

    @Override
    public List<EntrustVO> like(String str) {
        return entrustMapper.listLike(str);
    }

    @Override
    public Page<EntrustVO> like(String str, int current, int size) {
        return entrustMapper.pageLike(str, new Page<>(current, size));
    }

    @Override
    public boolean recording(String entrustId, String barcodeMachineNumber) {
        Entrust entrust = getById(entrustId);
        if (entrust.getStatus() != 2) {
            return false;
        }

        entrust.setStatus(4);
        entrust.setLabellingTime(new Date());
        entrust.setMachineNumber(barcodeMachineNumber);
        saveOrUpdate(entrust);
        return true;
    }

    @Override
    public boolean finish(String id) {
        Entrust entrust = getById(id);
        if (entrust.getStatus() != 4) {
            return false;
        }
        entrust.setStatus(5);
        saveOrUpdate(entrust);
        return true;
    }


    /**
     * 定时任务：在每天24点(0点)时，将超过上市时间且未完成的委托的状态改为失效(state = 6)
     * 超过委托“上市时间”中：日期day的24点后，还未完成的委托修改状态为失效
     */
    //@Override
    @Scheduled(cron = "0 0 0 * * ?")
    public void invalidate() {
        entrustMapper.invalidate();
    }

    @Override
    public EntrustDefaultInfoVO defaultInfo(String userId) {
        Entrust lastEntrust = entrustMapper.getLastEntrustByUserId(userId);
        EntrustDefaultInfoVO vo = new EntrustDefaultInfoVO();
        if (lastEntrust != null) {
            String poultryId = lastEntrust.getPoultryId();
            PoultryCategory poultry = categoryService.getById(poultryId);
            if (poultry != null) {
                vo.setPoultryId(poultry.getPoultryCategoryId());
                vo.setPoultryNumber(poultry.getPoultryCategoryNumber());
                vo.setPoultryName(poultry.getPoultryCategoryName());
            }
            String toMarketId = lastEntrust.getToMarketId();
            ToMarket toMarket = marketService.getById(toMarketId);
            if (toMarket != null) {
                vo.setToMarketId(toMarket.getSlaughterHouseId());
                vo.setToMarketName(toMarket.getSlaughterHouseName());
            }
            Integer stallsId = lastEntrust.getStallsId();
            Stalls stall = stallsService.getById(stallsId);
            if (stall != null) {
                vo.setStallId(stall.getStallsId());
                vo.setStallName(stall.getStallsName());
                //改到了这里
                SlaughterHouse slaughterHouse = houseService.getById(stall.getSlaughterHouseId());
                //SlaughterHouse slaughterHouse = slaughterHouseDao.getOne(Integer.valueOf(stall.getSlaughterHouseId()));
                vo.setSlaughterHouseId(slaughterHouse.getSlaughterHouseId());
                vo.setSlaughterHouseName(slaughterHouse.getSlaughterHouseName());
                vo.setProvince(slaughterHouse.getProvince());
                vo.setCity(slaughterHouse.getCity());
                vo.setDistrict(slaughterHouse.getDistrict());
                vo.setAddress(slaughterHouse.getAddress());
            }
        }
        Date today = new Date();
        vo.setGoMarketTime(today.getHours() < 16 ? today : dateUtils.getDateAfterDaysDate(1, today));
        return vo;
    }

    @Override
    public IPage<Entrust> findGoMarketTodayByUser(String userId, Integer current, Integer size) {
        Page<Entrust> page = new Page<>(current, size);

        return entrustMapper.findGoMarketTodayByUserId(userId, page);
    }

    @Override
    public IPage<Entrust> findGoMarketTodayByUser(String userId, Integer status, Integer current, Integer size) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.findGoMarketTodayByUserId(userId, status, page);
    }

    @Override
    public IPage<Entrust> findGoMarketTodayByToMarket(String toMarketId, Integer current, Integer size) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.findGoMarketTodayByToMarket(toMarketId, page);
    }

    @Override
    public IPage<Entrust> findGoMarketTodayByToMarket(String toMarketId, Integer status, Integer current, Integer size) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.findGoMarketTodayByToMarket(toMarketId, status, page);
    }

    @Override
    public IPage<Entrust> findGoMarketTodayByStalls(String stallsId, Integer current, Integer size) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.findGoMarketTodayByStalls(stallsId, page);
    }

    @Override
    public IPage<Entrust> findGoMarketTodayByStalls(String stallsId, Integer status, Integer current, Integer size) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.findGoMarketTodayByStalls(stallsId, status, page);
    }

    @Override
    public String reLabel(String entrustId, String barcodeMachineNumber) {
        Entrust entrust = getById(entrustId);
        if (entrust.getStatus() != 5) {
            //不是已经完成的订单
            return "not finish";
        }
        // 完成上一单
        entrustMapper.updateStateByBarcodeNumberAndState(barcodeMachineNumber, 4, 5);
        // 当天订单变为“正在贴标”
        entrust.setStatus(4);
        Date now = new Date();
        entrust.setLabellingTime(now);
        entrust.setMachineNumber(barcodeMachineNumber);
        // 将该单标记为“再次贴标”
        entrust.setIsReLabelling(1);
        entrust.setReLabellingTime(now);
        saveOrUpdate(entrust);
        String uuid = UUIDUtils.getUUID20();
        //存入键值对到redis
        redisUtil.set(uuid, entrust.getEntrustId() + "_" + barcodeMachineNumber, timeout);
        return uuid;
    }

    @Override
    public IPage<Entrust> historyByUser(String userId, Integer current, Integer size, Date from, Date to) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.historyByUser(userId, page, from, to);
    }

    @Override
    public IPage<Entrust> historyByUserAndStatus(String userId, Integer status, Integer current, Integer size, Date from, Date to) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.historyByUserAndStatus(userId, status, page, from, to);
    }

    @Override
    public IPage<Entrust> historyByToMarket(String toMarketId, Integer current, Integer size, Date from, Date to) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.historyByToMarket(toMarketId, page, from, to);
    }

    @Override
    public IPage<Entrust> historyByToMarketAndState(String toMarketId, Integer status, Integer current, Integer size, Date from, Date to) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.historyByToMarketAndState(toMarketId, status, page, from, to);
    }

    @Override
    public IPage<Entrust> historyByStalls(String stallsId, Integer current, Integer size, Date from, Date to) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.historyByStalls(stallsId, page, from, to);
    }

    @Override
    public IPage<Entrust> historyByStallsAndState(String stallsId, Integer status, Integer current, Integer size, Date from, Date to) {
        Page<Entrust> page = new Page<>(current, size);
        return entrustMapper.historyByStallsAndState(stallsId, status, page, from, to);
    }

    @Override
    public String viewQRCode(String entrustId, String barcodeMachineNumber) {
        Entrust entrust = getById(entrustId);
        if (entrust.getStatus() != 2) {
            return "error";
        }
        // 完成上一单
        entrustMapper.updateStateByBarcodeNumberAndState(barcodeMachineNumber, 4, 5);
        entrust.setStatus(4);
        entrust.setLabellingTime(new Date());
        entrust.setMachineNumber(barcodeMachineNumber);
        saveOrUpdate(entrust);
        String uuid = UUIDUtils.getUUID20();
        redisUtil.set(uuid, barcodeMachineNumber + "_" + entrust.getEntrustId(), timeout);
        return uuid;
    }
}
